﻿# -*- coding: UTF-8 -*-

import requests
import json
import time
import random
import hashlib
import re
import numpy as np
import cv2
import ddddocr

import execjs
from PIL import Image
import urllib

def generate_distance1(slice_url, bg_url):
    """
    :param bg_url: 背景图地址
    :param slice_url: 滑块图地址
    :return: distance
    :rtype: Integer
    """
    slide = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)

    with open(slice_url, 'rb') as file:
        slice_image = file.read()

    with open(bg_url, 'rb') as file:
        bg_image = file.read()

    # slice_image = requests.get(slice_url).content
    # bg_image = requests.get(bg_url).content
    
    result = slide.slide_match(slice_image, bg_image, simple_target=True)
    return result['target'][0]


def linear_interpolation(start, end, num_points):
    """
    使用线性插值生成从起点到终点的点。
    
    :param start: 起点坐标 (x, y)
    :param end: 终点坐标 (x, y)
    :param num_points: 要生成的点数
    :return: 生成的点列表 [(x, y), ...]
    """
    points = []
    for i in range(num_points):
        t = i / (num_points - 1)
        x = start[0] + t * (end[0] - start[0])
        y = start[1] + t * (end[1] - start[1])
        points.append((round(x), round(y)))
    return points


def generate_mouse_trajectory(start, end, duration=4000.0, num_points=100):
    """
    生成鼠标运动轨迹。
    
    :param start: 起点坐标 (x, y)
    :param end: 终点坐标 (x, y)
    :param duration: 总时长（秒）
    :param num_points: 轨迹点数量
    :return: 包含 (x, y, time,mouseevent) 的轨迹列表
    """
    # 使用线性插值生成点
    curve_points = linear_interpolation(start, end, num_points)

    # 添加随机扰动使轨迹更自然
    # curve_points = [
    #     (x + random.randint(-2, 2), y + random.randint(-2, 2))
    #     for x, y in curve_points
    # ]
    curve_points[0]=start
    curve_points[-1]=end

    # 生成时间点
    t_values = np.linspace(0, duration, num_points)
    start_time = int(time.time()*1000)
    int_t_values = [int(t) for t in t_values]

    time_points = [start_time + t for t in int_t_values]
    
    # 生成轨迹
    #trajectory = list(zip(curve_points, time_points))
    

     # 生成轨迹 (x, y, time)
    trajectory = [(x, y, t,"mousemove") for (x, y), t in zip(curve_points, time_points)]


    # x,y,t,e=trajectory[0]
    # trajectory[0]=(x,y,t,"mousedown")

    # x,y,t,e=trajectory[-1]
    # trajectory[-1]=(x,y,t,"mouseup")


    # 将trajectory的第一个元素转换为列表，修改后转换回元组
    trajectory[0] = list(trajectory[0])
    trajectory[0][3] = "mousedown"
    trajectory[0] = tuple(trajectory[0])

    # 将trajectory的最后一个元素转换为列表，修改后转换回元组
    trajectory[-1] = list(trajectory[-1])
    trajectory[-1][3] = "mouseup"
    trajectory[-1] = tuple(trajectory[-1])    
    return trajectory




def generate_slide_trajectory(distance):
    """
    生成滑动轨迹

    Args:
        distance (int): 滑动距离

    Returns:
        list: 滑动轨迹，包括鼠标事件的时间、坐标和事件类型

    """
    trajectory = []
    current_x = 0
    current_y = random.randint(400, 440)
    start_time = int(time.time() * 1000)
    
    # 添加初始的mousedown事件
    trajectory.append({
        'x': current_x,
        'y': current_y,
        't': start_time,
        'e': 'mousedown'
    })
    
    while current_x < distance:
        # 随机生成x方向的移动距离
        step = random.randint(1, 2)
        current_x = min(current_x + step, distance)
        
        # y方向小幅度随机波动
        current_y += random.randint(-1, 1)
        
        # 时间递增，模拟人类操作的时间间隔
        start_time += random.randint(10, 100)
        
        trajectory.append({
            'x': current_x,
            'y': current_y,
            't': start_time,
            'e': 'mousemove'
        })
    
    # 添加最后的mouseup事件
    start_time += random.randint(10, 100)
    trajectory.append({
        'x': current_x,
        'y': current_y,
        't': start_time,
        'e': 'mouseup'
    })
    
    return trajectory




def download_image(sesson:requests.Session, url: str, save_path: str) -> bool:
    """
    下载图片并保存到指定路径
    :param url: 图片URL
    :param save_path: 保存路径，包含文件名
    :return: 下载是否成功
    """
    try:
        # 从URL下载图片
        response = session.get(url)
        response.raise_for_status()  # 检查请求是否成功
        
        # 保存图片到指定路径
        with open(save_path, 'wb') as f:
            f.write(response.content)
        return True
    except Exception as e:
        print(f"下载图片失败: {str(e)}")
        return False


def captcha_test(tracks):
    with open('slider_captcha.js', 'r', encoding='utf-8') as fp:
        js = fp.read()
    ctx = execjs.compile(js)
    token = ctx.call("get_token", tracks)
    return token


if __name__ == '__main__':


    session=requests.Session()

    cookies = {
        'global_cookie': 'osdq5zpcb2az40allm7m7xknql2m96gtlo8',
        'city': 'www1',
        'otherid': 'bd0e8cd439cda19f6a03eb0558475b5a',
        'token': '38099e3618ce4b98ae846317f7088656',
        'g_sourcepage': 'txz_dl%5Egg_pc',
        'unique_cookie': 'U_z8dzzbmtgveys032jakeg9j8m19m9i52z07*2',
        '__utma': '147393320.1799272592.1743993706.1744601046.1744699584.6',
        '__utmc': '147393320',
        '__utmz': '147393320.1744699584.6.6.utmcsr=www1.fang.com|utmccn=(referral)|utmcmd=referral|utmcct=/',
        '__utmt_t0': '1',
        '__utmt_t1': '1',
        '__utmb': '147393320.2.10.1744699584',
    }

    headers = {
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5',
        'Connection': 'keep-alive',
        # 'Content-Length': '0',
        'Origin': 'https://passport.fang.com',
        'Referer': 'https://passport.fang.com/?backurl=https%3A%2F%2Fwww1.fang.com%2F',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-origin',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0',
        'X-Requested-With': 'XMLHttpRequest',
        'sec-ch-ua': '"Microsoft Edge";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        # 'Cookie': 'global_cookie=osdq5zpcb2az40allm7m7xknql2m96gtlo8; city=www1; otherid=bd0e8cd439cda19f6a03eb0558475b5a; token=38099e3618ce4b98ae846317f7088656; g_sourcepage=txz_dl%5Egg_pc; unique_cookie=U_z8dzzbmtgveys032jakeg9j8m19m9i52z07*2; __utma=147393320.1799272592.1743993706.1744601046.1744699584.6; __utmc=147393320; __utmz=147393320.1744699584.6.6.utmcsr=www1.fang.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmt_t0=1; __utmt_t1=1; __utmb=147393320.2.10.1744699584',
    }



    response = session.post('https://passport.fang.com/getslidecodeinit.api', cookies=cookies, headers=headers)

    result=response.json()

    print("get slidecode init:",result)


    gt=result["gt"]
    challenge=result["challenge"]


    headers = {
        'Accept': '*/*',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5',
        'Connection': 'keep-alive',
        'Referer': 'https://passport.fang.com/',
        'Sec-Fetch-Dest': 'script',
        'Sec-Fetch-Mode': 'no-cors',
        'Sec-Fetch-Site': 'same-site',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0',
        'sec-ch-ua': '"Microsoft Edge";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        # 'Cookie': 'global_cookie=osdq5zpcb2az40allm7m7xknql2m96gtlo8; city=www1; otherid=bd0e8cd439cda19f6a03eb0558475b5a; token=38099e3618ce4b98ae846317f7088656; g_sourcepage=txz_dl%5Egg_pc; unique_cookie=U_z8dzzbmtgveys032jakeg9j8m19m9i52z07*2; __utma=147393320.1799272592.1743993706.1744601046.1744699584.6; __utmc=147393320; __utmz=147393320.1744699584.6.6.utmcsr=www1.fang.com|utmccn=(referral)|utmcmd=referral|utmcct=/; __utmt_t0=1; __utmt_t1=1; __utmb=147393320.2.10.1744699584',
    }

    print("get captcha image")


    cb_time=int(random.random() * 10000) + int(time.time() * 1000)
    url = f'https://recaptcha.fang.com/?c=index&a=jigsaw&gt={gt}&challenge={challenge}&callback=fangcheck_{cb_time}&_200226'
    print(url)


    response = session.get(url, headers=headers)

    value=response.text
    print(value)

    # Remove callback wrapper and parse JSON
    json_str = re.sub(r'^fangcheck_\d+\(|\)$', '', value)
    value_dict = json.loads(json_str)

    # Now you can access the data as a dictionary
    print(value_dict['url'])  # Outputs: 9bd4e5057d9cf.jpg
    print(value_dict['surl'])  # Outputs: 17b02ed01ff333.png



    # 使用示例

    url = f'https://static.soufunimg.com/common_m/m_recaptcha/jigsawimg/{value_dict["url"]}'
    filename = "bg.jpg"
    save_path = filename  # 保存到当前目录
    download_image(session,url, filename)

    url = f'https://static.soufunimg.com/common_m/m_recaptcha/jigsawimg/{value_dict["surl"]}'
    download_image(session,url, "slider.png")



    # 打开并缩放背景图片
    bg_image = Image.open("bg.jpg")
    resized_bg = bg_image.resize((300, 150), Image.Resampling.LANCZOS)
    resized_bg.save("bg.jpg")



    slider_image = Image.open("slider.png")
    resized_slider = slider_image.resize((57, 150), Image.Resampling.LANCZOS)
    resized_slider.save("slider.png")


    distance=generate_distance1("slider.png", "bg.jpg")
    print("distance:",distance)

    # distance=generate_distance1("test.png", "bg.jpg")
    # print(distance)



    # 使用函数生成轨迹
    # start_point = (0, 314)
    # end_point = (distance, 363)
    # mouse_trajectory = generate_mouse_trajectory(start_point, end_point)


    # mouse_trajectory_dicts = [{'x': point[0], 'y': point[1], 't': point[2], 'e': point[3]} for point in mouse_trajectory]



    mouse_trajectory_dicts=generate_slide_trajectory(distance)




    # 将轨迹字典列表转换为 JSON 格式的字符串
    mouse_trajectory_json = json.dumps(mouse_trajectory_dicts, indent=4)
    # print(type(mouse_trajectory_json))
    # print(mouse_trajectory_json)


    token=captcha_test(mouse_trajectory_json)


    value_i=token['value_i']
    value_t=token['value_t']

    # start=mouse_trajectory[0][2]
    # end=mouse_trajectory[-1][2]

    start=mouse_trajectory_dicts[0]['t']
    end=mouse_trajectory_dicts[-1]['t']
    cb_time=int(random.random() * 10000) + int(time.time() * 1000)

    headers = {
        'Accept': '*/*',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5',
        'Connection': 'keep-alive',
        'Referer': 'https://passport.fang.com/',
        'Sec-Fetch-Dest': 'script',
        'Sec-Fetch-Mode': 'no-cors',
        'Sec-Fetch-Site': 'same-site',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36 Edg/135.0.0.0',
        'sec-ch-ua': '"Microsoft Edge";v="135", "Not-A.Brand";v="8", "Chromium";v="135"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        # 'Cookie': 'global_cookie=osdq5zpcb2az40allm7m7xknql2m96gtlo8; city=www1; __utma=147393320.1799272592.1743993706.1744362594.1744601046.5; __utmc=147393320; __utmz=147393320.1744601046.5.5.utmcsr=bing|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); token=23af3f4343d74dc9b7d40c39dd6e33ba; g_sourcepage=txz_dl%5Egg_pc; unique_cookie=U_a6j6l574xxe4pylsgbv3ghhtm25m9gieztg*3',
    }

    print("i:",value_i)
    print("t:",value_t)




    url = f'https://recaptcha.fang.com/?c=index&a=codeDrag&start={start}&end={end}&i={value_i}&t={value_t}&gt={gt}&challenge={challenge}&callback=fangcheck_{cb_time}&_200226'

    print("url:",url)

    encoded_url=url
    # encoded_url = urllib.parse.quote(url, safe=':/?=&')
    # print(encoded_url)


    response = session.get(
       encoded_url,
       headers=headers
    )


    # response = session.get(
    #    url,
    #    headers=headers
    # )

    print(response.text)















